home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
ORBMECHD
/
PSTR_TO_.C
< prev
Wrap
Text File
|
1990-09-20
|
5KB
|
272 lines
/************************************************
Program to convert a Pascal string to an extended
precision real number.
7 May 90
************************************************/
#include "orbmech.h"
#include "SANE.h"
#include "convert.h"
/*******************************************/
extended ext_pow( x, y )
extended x, y;
{
int i, j;
extended value;
value = x;
for ( i = 2; i <= y; i++ )
value *= x;
return (value);
}
/*******************************************/
Pstr_to_extended( The_str, return_number, success )
Str255 The_str;
extended *return_number;
Boolean *success;
{
extended sig_fig[30], abs_p_d;
int exp_fig[10], dec_pos = 0, exp_size = 0, sig_size = 0, l = 0;
int abs_place = 0, i = 0, j = 0, temp = 0, exp_value = 0, k = 0;
Boolean exp_start = 0, dec_found = 0, sig_neg = 0, exp_neg = 0;
char temp_char;
temp = The_str[0];
*success = 1;
for( i = 1; i <= temp; i++) {
temp_char = The_str[i];
if (sig_size > 30) {
Alert( SIG_OVERFLOW, NIL_POINTER );
*success = 0;
break;
}
if (exp_size > 10) {
Alert( EXP_OVERFLOW, NIL_POINTER );
*success = 0;
break;
}
if ( !exp_start ) {
switch ( temp_char ) {
case ZERO:
sig_size++;
sig_fig[sig_size] = 0.0;
break;
case ONE:
sig_size++;
sig_fig[sig_size] = 1.0;
break;
case TWO:
sig_size++;
sig_fig[sig_size] = 2.0;
break;
case THREE:
sig_size++;
sig_fig[sig_size] = 3.0;
break;
case FOUR:
sig_size++;
sig_fig[sig_size] = 4.0;
break;
case FIVE:
sig_size++;
sig_fig[sig_size] = 5.0;
break;
case SIX:
sig_size++;
sig_fig[sig_size] = 6.0;
break;
case SEVEN:
sig_size++;
sig_fig[sig_size] = 7.0;
break;
case EIGHT:
sig_size++;
sig_fig[sig_size] = 8.0;
break;
case NINE:
sig_size++;
sig_fig[sig_size] = 9.0;
break;
case POINT:
if (dec_found ) {
*success = 0;
Alert( MULT_PT, NIL_POINTER );
break;
}
else {
dec_pos = sig_size;
dec_found = 1;
}
case SPACE:
continue;
break;
case COMMA:
continue;
break;
case LET_D:
exp_start = 1;
break;
case LET_E:
exp_start = 1;
break;
case MINUS:
if ( i == 1 )
sig_neg = 1;
else {
*success = 0;
Alert( NON_START_MINUS, NIL_POINTER );
break;
}
break;
default:
*success = 0;
Alert( BAD_CHARACTER, NIL_POINTER );
break;
}
}
else {
switch ( temp_char ) {
case ZERO:
exp_size++;
exp_fig[ exp_size ] = 0;
break;
case ONE:
exp_size++;
exp_fig[ exp_size ] = 1;
break;
case TWO:
exp_size++;
exp_fig[ exp_size ] = 2;
break;
case THREE:
exp_size++;
exp_fig[ exp_size ] = 3;
break;
case FOUR:
exp_size++;
exp_fig[ exp_size ] = 4;
break;
case FIVE:
exp_size++;
exp_fig[ exp_size ] = 5;
break;
case SIX:
exp_size++;
exp_fig[ exp_size ] = 6;
break;
case SEVEN:
exp_size++;
exp_fig[ exp_size ] = 7;
break;
case EIGHT:
exp_size++;
exp_fig[ exp_size ] = 8;
break;
case NINE:
exp_size++;
exp_fig[ exp_size ] = 9;
break;
case MINUS:
if ( exp_size == 0 )
exp_neg = 1;
else {
*success = 0;
Alert( EXP_NON_START_MINUS, NIL_POINTER );
break;
}
break;
case SPACE:
continue;
break;
case POINT:
*success = 0;
Alert( DEC_PT_IN_EXP, NIL_POINTER );
break;
case COMMA:
continue;
break;
default:
*success = 0;
Alert( BAD_CHAR, NIL_POINTER );
break;
}
}
if ( !*success ) i = temp + 2;
}
if ( *success ) {
if ( dec_found == 0 )
dec_pos = sig_size;
k = 1;
if ( exp_start ) {
for ( j = exp_size; j > 0; j-- ) {
if ( j > 1 )
exp_value += exp_fig[ k ] * i_pow( 10, j - 1 );
else
exp_value += exp_fig[ k ];
k++;
}
}
if ( exp_neg )
exp_value *= - 1;
abs_place = dec_pos + exp_value - 1;
abs_p_d = abs_place * 1.0;
*return_number = 0.0;
for( i = 1; i <= sig_size; i++ ) {
if ( abs_p_d > 0 )
*return_number += sig_fig[ i ] * ext_pow( 10.0, abs_p_d ) ;
else if ( abs_p_d == 0 )
*return_number += sig_fig[ i ];
else
*return_number += sig_fig[ i ] / ext_pow( 10.0, - abs_p_d ) ;
abs_p_d--;
}
if ( sig_neg )
*return_number *= - 1.0 ;
}
}
/*******************************************/
int i_pow( x, y )
int x, y;
{
int i, j, value;
value = x;
for ( i = 2; i <= y; i++ )
value *= x;
return (value);
}